package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.api.user.IUserClient;
import com.heima.api.wemedia.WemediaClient;
import com.heima.comment.dtos.RepayDto;
import com.heima.comment.pojos.Comment;
import com.heima.comment.pojos.CommentLikes;
import com.heima.comment.pojos.Repay;
import com.heima.comment.service.ICommentRepayService;
import com.heima.comment.vos.RepayVo;
import com.heima.common.constants.WmNewsConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.AppThreadLocalUtil;
import com.heima.utils.common.SensitiveWordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentRepayServiceImpl implements ICommentRepayService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IUserClient userClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WemediaClient wemediaClient;
    /**
     * 游客Id
     */
    private static final Integer VISITOR_ID = 0;

    /**
     * 评论回复
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult save(RepayDto dto) {
        if (VISITOR_ID.equals(AppThreadLocalUtil.getUser())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (StringUtils.isEmpty(dto.getContent()) || StringUtils.isEmpty(dto.getCommentId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        log.info("评论回复:{}", dto);
        if (!check(dto.getContent())) {
            return ResponseResult.errorResult(400, "评论内容包含敏感词");
        }
        log.info("审核通过！");
        ApUser userById = userClient.getUserById(AppThreadLocalUtil.getUser());
        Repay repay = new Repay();
        BeanUtils.copyProperties(dto, repay);
        repay.setCreatedTime(new Date());
        repay.setImage(userById.getImage());
        repay.setAuthorId(userById.getId());
        repay.setAuthorName(userById.getName());
        repay.setLikes(0);
        mongoTemplate.save(repay);
        addCommentCount(dto.getCommentId());
        return ResponseResult.okResult(200, "评论回复成功");
    }

    /**
     * 评论数加一
     */
    public void addCommentCount(String articleId) {
        Comment byId = mongoTemplate.findById(articleId, Comment.class);
        Integer reply = byId.getReply();
        byId.setReply(reply == null ? 1 : reply + 1);
        mongoTemplate.save(byId);
    }

    /**
     * 敏感词审核
     *
     * @param text
     * @return
     */
    public boolean check(String text) {
        boolean flag = true;
        if (StringUtils.isEmpty(text)) {
            //评论内容为空,不审核
            return true;
        }
        Object str = redisTemplate.opsForValue().get(WmNewsConstants.SENSITIVE_KEY);
        List<String> all = null;
        if (ObjectUtils.isEmpty(str)) {
            //redis敏感词为空,从数据库中查
            List<WmSensitive> wmSensitives = wemediaClient.findAll();
            all = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
        } else {
            all = JSONArray.parseArray(str + "", String.class);
        }
        SensitiveWordUtil.initMap(all);
        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (!CollectionUtils.isEmpty(map)) {
            //有违规内容
            log.info("审核不通过,文章内容包含违规内容：{}", map);
            return false;
        }
        return flag;
    }


    /**
     * 评论回复列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(RepayDto dto) {
        if (ObjectUtils.isEmpty(dto.getCommentId()) || ObjectUtils.isEmpty(dto.getMinDate())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        Date date = new Date(dto.getMinDate());
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(date))
                .with(Sort.by(Sort.Direction.DESC, "createdTime"));
        List<Repay> repays = mongoTemplate.find(query, Repay.class);
        List<RepayVo> collect = repays.stream().map(repay -> {
            RepayVo repayVo = new RepayVo();
            BeanUtils.copyProperties(repay, repayVo);
            repayVo.setCreatedTime(repay.getCreatedTime().getTime());
            // 获取当前时间的Calendar实例
            Calendar calendar = Calendar.getInstance();

            // 减去24小时
            calendar.add(Calendar.HOUR_OF_DAY, -24);

            // 获取24小时前的Date对象
            Date oneDayAgo = calendar.getTime();
            List<CommentLikes> commentLikes = mongoTemplate.find(Query.query(Criteria.where("commentId").is(repay.getId())
                    .and("authorId").is(repay.getAuthorId())
                    .and("createdTime").gte(oneDayAgo)), CommentLikes.class);
            if (!CollectionUtils.isEmpty(commentLikes)) {
                repayVo.setOperation((short) 0);
            }
            return repayVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(collect);
    }

    /**
     * 评论回复点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(RepayDto dto) {
        Integer userId = AppThreadLocalUtil.getUser();
        if (VISITOR_ID.equals(userId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (StringUtils.isEmpty(dto.getCommentRepayId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getOperation() == 0) {
            //点赞
            CommentLikes commentLikes = new CommentLikes();
            commentLikes.setCommentId(dto.getCommentRepayId());
            commentLikes.setAuthorId(userId);
            commentLikes.setCreatedTime(new Date());
            mongoTemplate.save(commentLikes);
            commentCount(dto.getCommentRepayId(), 1);
        } else {
            //取消点赞
            mongoTemplate.remove(Query.query(Criteria.where("authorId").is(userId).and("commentId").is(dto.getCommentId())), CommentLikes.class);
            commentCount(dto.getCommentRepayId(), 0);
        }
        return ResponseResult.okResult("SUCCESS");
    }

    /**
     * 评论回复点赞数
     * @param commentRepayId
     * @param operation
     */
    private void commentCount(String commentRepayId, Integer operation) {
        Repay byId = mongoTemplate.findById(commentRepayId, Repay.class);
        Integer likes = byId.getLikes();
        Integer count = operation == 0 ? likes - 1 : likes + 1;
        byId.setLikes(count);
        mongoTemplate.save(byId);
    }
}
